package com.startit.csv;

import java.lang.reflect.Method;
import java.util.*;

import com.startit.csv.CSVField.ValidationType;
import com.startit.csv.annotation.*;

public class CSVFormat {
	private List<CSVField> fields = new LinkedList<CSVField>();
	private char delimeter;
	private char quote;
	private boolean fixWidth;
	private Class mappingBean;

	public CSVFormat(char delimeter, char quote) {
		super();
		this.delimeter = delimeter;
		this.quote = quote;
	}

	public void addField(CSVField field) {
		this.fields.add(field);
	}

	public int getFieldsSize() {
		return this.fields.size();
	}

	public List<CSVField> getFields() {
		return fields;
	}

	public void setFields(List<CSVField> fields) {
		this.fields = fields;
	}

	public char getDelimeter() {
		return delimeter;
	}

	public void setDelimeter(char delimeter) {
		this.delimeter = delimeter;
	}

	public char getQuote() {
		return quote;
	}

	public void setQuote(char quote) {
		this.quote = quote;
	}

	public boolean isFixWidth() {
		return fixWidth;
	}

	public void setFixWidth(boolean fixWidth) {
		this.fixWidth = fixWidth;
	}

	public Class getMappingBean() {
		return mappingBean;
	}

	@SuppressWarnings("unchecked")
	public void setMappingBean(Class mappingBean) {
		if (mappingBean==null)
			return;
		if (this.mappingBean!=null && this.mappingBean.getName().equals(mappingBean.getName()))
			return;
		this.mappingBean = mappingBean;
		this.fields = new LinkedList<CSVField>();
		for (Method m : mappingBean.getMethods()) {
			String name = m.getName();
			if (name.startsWith("set") && m.getParameterTypes().length==1 && m.isAnnotationPresent(Field.class)) {
				name = name.substring(3, 4).toLowerCase()+name.substring(4);
				CSVField f = new CSVField(name,m.getParameterTypes()[0]);
				if (m.isAnnotationPresent(Required.class)) {
					f.addValidation(ValidationType.REQUIRED, null);
				}
				if (m.isAnnotationPresent(MaxLength.class)) {
					f.addValidation(ValidationType.MAXLENGTH, m.getAnnotation(MaxLength.class).value());
				}
				if (m.isAnnotationPresent(Min.class)) {
					f.addValidation(ValidationType.MIN, m.getAnnotation(Min.class).value());
				}
				if (m.isAnnotationPresent(Max.class)) {
					f.addValidation(ValidationType.MAX, m.getAnnotation(Max.class).value());
				}
				if (m.isAnnotationPresent(Matches.class)) {
					f.addValidation(ValidationType.MATCH, m.getAnnotation(Matches.class).value());
				}
				f.setOrder(m.getAnnotation(Field.class).order());
				this.addField(f);
			}
		}
		Collections.sort(this.fields);
	}

}
